package org.example.controller;


import com.alibaba.fastjson.JSONObject;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Paths;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.example.config.ResponseResult;
import org.example.entity.SysDept;
import org.example.entity.SysTestConfig;
import org.example.pojo.*;
import org.example.service.*;
import org.example.util.ExcelExportUtils;
import org.example.util.MinioUtils;
import org.springdoc.core.configuration.SpringDocConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;


/**
 * @author wxm
 * @date 2025/2/11 16:22
 * 测试
 */
@RestController
@RequestMapping("/demo/")
@Tag(name = "示例接口", description = "示例接口分类")
@Slf4j
public class DemoController {
    @Autowired
    private DemoService demoService;
    @Autowired
    private SysTestConfigService sysTestConfigService;
    @Autowired
    private MinioUtils minioUtils;
    @Autowired
    private DictionariesService dictionariesService;
    @Autowired
    private SysContService sysContService;
    @Autowired
    private DatasourceService datasourceService;
    @Autowired
    private OpenAPI openAPI;
    @Autowired
    private SpringDocConfiguration springDocConfiguration;
    @GetMapping("/")
    public String hello() {
        return "Hello, Dapr with Java!";
    }

    /**
     * 查询全部的配置数据
     *
     * @return 文件内容
     */
    @GetMapping("selectConfList")
    public ResponseResult<List<SysTestConfig>> demo() {
        return ResponseResult.success(sysTestConfigService.selectConfigs());
    }

    /**
     * 保存一条配置
     *
     * @param sysTestConfig 配置数据
     * @return 保存结果
     */
    @PostMapping("saveConfig")
    private ResponseResult<String> saveConfig(@RequestBody SysTestConfigDto sysTestConfig) {
        sysTestConfigService.saveConfig(sysTestConfig);
        return ResponseResult.success();
    }

    /**
     * 删除一条配置数据
     *
     * @param id id
     * @return 返回结果
     */
    @GetMapping("delConfig")
    public ResponseResult<String> delConfig(Integer id) {
        return ResponseResult.success(sysTestConfigService.delConfig(id));
    }

    /**
     * 更新数据
     * @param sysTestConfig 更新数据
     * @return  返回结果
     */
    @PostMapping("upConfig")
    public ResponseResult<String> upConfig(@RequestBody SysTestConfigDto sysTestConfig) {
        sysTestConfigService.upConfig(sysTestConfig);
        return ResponseResult.success();
    }

    /**
     * 通过url询对应的配置数据
     * @param url url
     * @return 返回结果
     */
    @GetMapping("selectConfigJson")
    public ResponseResult<SysTestConfigVo> selectConfig(String url) {
        return ResponseResult.success(sysTestConfigService.selectConfig(url));
    }

    @PostMapping("selectDataByConfig")
    public ResponseResult<List<Map<String, Object>>> selectDataByConfig(@RequestBody DemoDto demoDto) {
        // , String url
        return ResponseResult.success(sysTestConfigService.selectDataByConfig(demoDto,"add"));
    }

    /**
     * 创建json文件
     *
     * @param jsonObject 文件内容
     * @return 创建结果
     */
    @PostMapping("create")
    public JSONObject create(@RequestBody JSONObject jsonObject) {
        System.out.println("jsonObject = " + jsonObject);
        return demoService.create(jsonObject);
    }

    /**
     * 查询
     *
     * @return 查询结果
     */
    @GetMapping("select")
    public List<DemoVo> select() {
        return demoService.select();
    }

    /**
     * 查询数据库中的所有表
     *
     * @return 表名集合
     */
    @GetMapping("allTableName")
    public ResponseResult<List<String>> allTableName(String keyword,String tableModule) {
        return ResponseResult.success(demoService.allTableName(keyword,tableModule));
    }

    /**
     * 通过 tableName 查询表中的所有字段
     *
     * @param tableName 表名
     * @return 字段集合
     */
    @GetMapping("getAllColumns")
    public ResponseResult<List<TableColumnDto>> getAllColumns(String tableName) {
        return ResponseResult.success(demoService.getAllColumns(tableName));
    }

    /**
     * 保存配置
     *
     * @param tableConfig 配置信息
     * @return 保存结果
     */
    // @PostMapping("saveConfig")
    // public <T> ResponseResult<T> saveConfig(@RequestBody TableConfigVo tableConfig) {
    //     demoService.saveConfig(tableConfig);
    //     return ResponseResult.success();
    // }

    /**
     * 导出Excel表格
     *
     * @param request       请求对象
     * @param response      返回对象
     * @param excelForSqlVo ExcelForSqlVo
     */
    @RequestMapping("/exportExcel")
    public void exportExcel(HttpServletRequest request, HttpServletResponse response, @RequestBody ExcelForSqlVo excelForSqlVo) throws IOException {
        List<ExcelForSql> excelForSqlList = excelForSqlVo.getExcelForSqlList();
        // 使用Stream API遍历并生成List<String>
        // Excel表列名
        List<String> comments = excelForSqlList.stream()
                .map(ExcelForSql::getComments) // 提取每个对象的columnName
                .toList();    // 收集到一个List中
        // 定义数据集合
        List<LinkedHashMap<String, Object>> dataLists = new ArrayList<>();
        // 查询数据
        List<Map<String, Object>> dataList = demoService.selectDataByTableName(excelForSqlVo.getTableName());
        // 遍历数据库中的数据
        for (Map<String, Object> stringObjectMap : dataList) {
            LinkedHashMap<String, Object> map = new LinkedHashMap<>();
            // 遍历前端传递的数据
            for (ExcelForSql excelForSql : excelForSqlList) {
                String object = stringObjectMap.get(excelForSql.getColumnName()).toString();
                map.put(excelForSql.getComments(), object);
            }
            dataLists.add(map);
        }
        ExcelExportUtils.exportExcel(comments, dataLists, excelForSqlVo.getSheetName(), "", response);
    }

    /**
     * 通过表名查询表数据
     *
     * @param tableName 表名
     * @return 表数据
     */
    @GetMapping("selectDataByTableName")
    public ResponseResult<List<Map<String, Object>>> selectDataByTableName(String tableName) {
        return ResponseResult.success(demoService.selectDataByTableName(tableName));
    }

    /**
     * 根据条件查询
     *
     * @param tableName  表名
     * @param rows       列数量
     * @param isSort     是否排序
     * @param sortColumn 排序字段
     * @return 返回数据
     */
    @GetMapping("/conditionSelect")
    public ResponseResult<List<Map<String, Object>>> conditionSelect(String tableName, String rows, Boolean isSort, String sortColumn) {
        return ResponseResult.success(demoService.selectDataByCondition(tableName, rows, isSort, sortColumn));
    }

    /**
     * 通过绑定关系查询数据
     *
     * @param jsonObject jsonObject
     * @return 返回的数据
     */
    @PostMapping("/relevanceSelect")
    public ResponseResult<List<Map<String, Object>>> relevanceSelect(@RequestBody JSONObject jsonObject) {
        return ResponseResult.success(demoService.relevanceSelect(jsonObject));
    }

    /**
     * 测试AOP功能
     *
     * @return 返回的数据
     */
    @GetMapping("/testAop")
    public ResponseResult<List<Map<String, Object>>> testAop() {
        return ResponseResult.success(demoService.testAop());
    }

    /**
     * 测试分页功能
     *
     * @param testPage testPage
     * @return 返回数据
     */
    @PostMapping("/testPage")
    public ResponseResult<List<SysDept>> testPage(@RequestBody TestPage testPage) {
        return ResponseResult.success(demoService.testPage(testPage));
    }

    /**
     * 测试Http工厂功能
     *
     * @return
     */
    @GetMapping("/testHttpGet")
    public ResponseResult<String> testHttp() {
        return ResponseResult.success(demoService.testHttpGet());
    }

    @PostMapping("/importExcel")
    public ResponseResult<String> importExcel(@RequestParam("file") MultipartFile file) {
        // 校验文件是否为空
        if (file.isEmpty()) {
            return ResponseResult.fail(1, "上传文件不能为空");
        }
        // 获取文件名并校验格式
        String fileName = file.getOriginalFilename();
        if (fileName == null || fileName.isEmpty()) {
            return ResponseResult.fail(2, "无效的文件名");
        }
        int dotIndex = fileName.lastIndexOf(".");
        if (dotIndex == -1 || !".xlsx".equalsIgnoreCase(fileName.substring(dotIndex))) {
            return ResponseResult.fail(3, "仅支持.xlsx格式的Excel文件");
        }
        return ResponseResult.success(demoService.importExcel(file));
    }

    /**
     * @param file     文件
     * @param fileName 文件名称
     * @Description 上传文件
     */
    @PostMapping("/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file, String fileName) {
        minioUtils.upload(file, fileName);
        return "上传成功";
    }

    /**
     * @param fileName 文件名称
     * @Description dowload文件
     */
    @GetMapping("/download")
    public ResponseEntity downloadFile(@RequestParam("fileName") String fileName) {
        return minioUtils.download(fileName);
    }

    /**
     * 查询字段表
     * @param parentColumn 数据类型
     * @return 返回的数据
     */
    @GetMapping("/getColumnType")
    public ResponseResult<List<String>> getColumnType(@RequestParam("parentColumn") String parentColumn) {
        return ResponseResult.success(dictionariesService.getColumnType(parentColumn));
    }

    /**
     * 查询所有的父键
     * @return 去重后的数据
     */
    @GetMapping("selectAllParent")
    public ResponseResult<List<String>> selectAllParent(){
        return ResponseResult.success(dictionariesService.selectAllParent());
    }

    /**
     * 通过父键查询所有的子健内容
     * @param parentName 父键
     * @return 返回子健
     */
    @GetMapping("getContentByParent")
    private ResponseResult<List<String>> getContentByParent(String parentName){
        return ResponseResult.success(sysContService.getContentByParent(parentName));
    }

    /**
     * 新增父键
     * @param parentName 父键名称
     */
    @PostMapping("insertParent")
    private void insertParent(String parentName){
        dictionariesService.insertParent(parentName);
    }

    /**
     * 新增子健
     * @param parentName 父键
     * @param sonName 子健
     */
    @PostMapping("insertSon")
    private void insertSon(String parentName,String sonName){
        dictionariesService.insertSon(parentName,sonName);
    }

    @PostMapping("/insertContByParent")
    private void insertContentByParent(String parentName,String content){
        sysContService.insertContentByParent(parentName,content);
    }

    @PostMapping("testSqlConnection")
    private  ResponseResult<?> testSqlConnection(@RequestBody DataSourceConfigDto config){
        return datasourceService.testConnection(config);
    }

    @GetMapping("getAllObjects")
        @Operation(summary = "获取所有的模式", description = "返回欢迎信息")
    public ResponseResult<List<String>> getAllObjects(){
        return ResponseResult.success(demoService.getAllObjects());
    }

    @GetMapping("/hello")
    @Operation(summary = "问候接口", description = "返回欢迎信息")
    public String hellos() {
        return "Hello, Swagger!";
    }

    @GetMapping("/getAllApis")
    @Operation(summary = "查询所有的API接口", description = "返回所有的API接口")
    public ResponseResult<List<Map<String,Object>>> getAllApis(){
        List<Map<String,Object>> list = new ArrayList<>();
        log.info("OpenAPI Schema: {}", openAPI.getOpenapi()); // 应输出3.0.1
        log.info("Paths: {}", openAPI.getPaths().keySet());   // 检查路径列表
        Paths paths = openAPI.getPaths();
        if (paths == null) {
            throw new IllegalStateException("OpenAPI paths未初始化！");
        }
        paths.forEach((k,v)->{
            Map<String,Object> map = new HashMap<>();
            map.put("url",k);
            map.put("method",v.readOperations().get(0).getOperationId());
            list.add(map);
        });
        return ResponseResult.success(list);
    }
}
